﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Text.RegularExpressions;

namespace Auto_Rename
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            //#if DEBUG
            //            patternSubtitle.Text = @"s03e<\d{2,}>";
            //            patternSubtitle_Dedicated.Text = @"mkv";
            //            patternMovie.Text = @"3x<\d{2,}>";
            //            patternMovie_Dedicated.Text = @"srt";
            //            folderToSearch.Text = @"Z:\Video\TV Series\The Big Bang Theory\The.Big.Bang.Theory.S03";
            //#endif
        }

        private void buttonRename_Click(object sender, RoutedEventArgs e)
        {
            DirectoryInfo dir1 = new DirectoryInfo(folderToSearch.Text);
            var allFiles = dir1.GetFiles().ToList();
            Dictionary<FileInfo, string> toRename = new Dictionary<FileInfo, string>();
            string messageToDisplay = "";
            string str1, str2;
            int i1;

            if (renameType_Matching.IsChecked == true)
            {
                #region Matching
                Regex movieRegex, subRegex, regexEqual;
                Dictionary<int, Regex> gi_Pattern_Source = new Dictionary<int, Regex>();
                Dictionary<int, Regex> gi_Pattern_Target = new Dictionary<int, Regex>();
                Match matchEqual;
                Match matchEqual_Source;
                Match matchEqual_Target;
                int sharedPatternCount;
                regexEqual = new Regex(@".*(?<gEqual>\<.+\>).*");

                string movieRegexPattern = "";
                i1 = 1;
                foreach (string fe1 in patternMovie.Text.Split(';'))
                {
                    string regex1_P = "";
                    matchEqual = regexEqual.Match(fe1);
                    if (matchEqual.Success)
                    {
                        for (int i2 = 0; i2 < matchEqual.Groups["gEqual"].Captures.Count; i2++)
                        {
                            regex1_P += ".*" + "(?<gE_" + i1.ToString() + ">" + matchEqual.Groups["gEqual"].Captures[i2].Value.Replace("<", "").Replace(">", "") + ")";
                        }
                        if (!string.IsNullOrWhiteSpace(regex1_P))
                        {
                            regex1_P += ".*";
                            gi_Pattern_Source.Add(i1, new Regex(regex1_P));
                        }
                    }
                    //
                    movieRegexPattern += string.Format(".*(?<g{0}>", i1) + fe1.Replace("<", "").Replace(">", "") + ")";
                    i1++;
                }
                sharedPatternCount = i1 - 1;

                i1 = 1;
                foreach (string fe1 in patternMovie_Dedicated.Text.Split(';'))
                {
                    movieRegexPattern += string.Format(".*(?<d{0}>", i1) + fe1 + ")+";
                    i1++;
                }
                movieRegexPattern += ".*";
                movieRegex = new Regex(movieRegexPattern);

                string subRegexPattern = "";
                i1 = 1;
                foreach (string fe1 in patternSubtitle.Text.Split(';'))
                {
                    string regex1_P = "";
                    matchEqual = regexEqual.Match(fe1);
                    if (matchEqual.Success)
                    {
                        for (int i2 = 0; i2 < matchEqual.Groups["gEqual"].Captures.Count; i2++)
                        {
                            regex1_P += ".*" + "(?<gE_" + i1.ToString() + ">" + matchEqual.Groups["gEqual"].Captures[i2].Value.Replace("<", "").Replace(">", "") + ")";
                        }
                        if (!string.IsNullOrWhiteSpace(regex1_P))
                        {
                            regex1_P += ".*";
                            gi_Pattern_Target.Add(i1, new Regex(regex1_P));
                        }
                    }
                    //
                    subRegexPattern += string.Format(".*(?<g{0}>", i1) + fe1.Replace("<", "").Replace(">", "") + ")";
                    i1++;
                }
                i1 = 1;
                foreach (string fe1 in patternSubtitle_Dedicated.Text.Split(';'))
                {
                    subRegexPattern += string.Format(".*(?<d{0}>", i1) + fe1 + ")+";
                    i1++;
                }
                subRegexPattern += ".*";
                subRegex = new Regex(subRegexPattern);

                Match movieMatch, subMatch;
                int countAlreadyMatched = 0;
                while (allFiles.Count > 0)
                {
                    FileInfo feFile = allFiles.First();
                    movieMatch = movieRegex.Match(feFile.Name.ToLower());
                    if (movieMatch.Success)
                    {
                        foreach (FileInfo feFile2 in allFiles.ToList())
                        {
                            subMatch = subRegex.Match(feFile2.Name.ToLower());
                            if (subMatch.Success)
                            {
                                if (System.IO.Path.GetFileNameWithoutExtension(feFile.Name.ToLower()) == System.IO.Path.GetFileNameWithoutExtension(feFile2.Name.ToLower()))
                                {
                                    if (feFile.Extension.ToLower() == feFile2.Extension.ToLower())
                                        continue;
                                    else
                                    {
                                        countAlreadyMatched++;
                                        break;
                                    }
                                }
                                //
                                bool isMatch = true;
                                try
                                {
                                    for (i1 = 1; i1 <= sharedPatternCount; i1++)
                                    {
                                        if (gi_Pattern_Source.ContainsKey(i1) && gi_Pattern_Target.ContainsKey(i1))
                                        {
                                            matchEqual_Source = gi_Pattern_Source[i1].Match(movieMatch.Groups["g" + i1.ToString()].Value);
                                            matchEqual_Target = gi_Pattern_Target[i1].Match(subMatch.Groups["g" + i1.ToString()].Value);
                                            //
                                            if (matchEqual_Source.Success && matchEqual_Target.Success && matchEqual_Source.Groups.Count == matchEqual_Target.Groups.Count)
                                            {
                                                for (int i2 = 1; i2 < matchEqual_Source.Groups.Count; i2++)
                                                {
                                                    if (matchEqual_Source.Groups["gE_" + i2.ToString()].Value != matchEqual_Target.Groups["gE_" + i2.ToString()].Value)
                                                    {
                                                        isMatch = false;
                                                        break;
                                                    }
                                                }
                                                if (!isMatch)
                                                    break;
                                            }
                                            else
                                            {
                                                isMatch = false;
                                                break;
                                            }
                                        }
                                        else
                                        {
                                            if (movieMatch.Groups["g" + i1.ToString()].Value != subMatch.Groups["g" + i1.ToString()].Value)
                                            {
                                                isMatch = false;
                                                break;
                                            }
                                        }
                                    }
                                }
                                catch (Exception)
                                {
                                    isMatch = false;
                                }
                                if (isMatch)
                                {
                                    if (!toRename.ContainsKey(feFile2))
                                        toRename.Add(feFile2, System.IO.Path.GetFileNameWithoutExtension(feFile.Name) + feFile2.Extension);
                                    allFiles.Remove(feFile2);
                                    break;
                                }
                            }
                        }
                    }
                    //
                    allFiles.Remove(feFile);
                }
                //
                messageToDisplay = string.Format(Properties.Resources.Message_AutoRename, countAlreadyMatched, toRename.Count);
                #endregion
            }
            else if (renameType_Cleanup.IsChecked == true)
            {
                #region Cleanup
                str1 = cleanup_ToClean.Text;
                if (cleanup_CaseSensitive.IsChecked != true)
                    str1 = str1.ToLower();
                List<string> toClean = str1.Split(new char[] { ';' }).ToList();
                //
                foreach (FileInfo feFile in allFiles)
                {
                    str1 = feFile.Name;
                    bool isCleaned = false;
                    foreach (string feToClean in toClean)
                    {
                        do
                        {
                            str2 = str1;
                            if (cleanup_CaseSensitive.IsChecked != true)
                                str2 = str2.ToLower();
                            i1 = str2.IndexOf(feToClean);
                            if (i1 >= 0)
                            {
                                isCleaned = true;
                                str2 = str2.Remove(i1, feToClean.Length);
                                str1 = str1.Remove(i1, feToClean.Length);
                            }
                        } while (str2.Contains(feToClean));
                    }
                    //
                    if (isCleaned)
                        toRename.Add(feFile, str1);
                }
                //
                messageToDisplay = string.Format(Properties.Resources.Message_CleanUp, toRename.Count);
                #endregion
            }
            //
            if (MessageBox.Show(this, string.Format(Properties.Resources.Message_Confirm, messageToDisplay), "", MessageBoxButton.YesNo, MessageBoxImage.Information) == MessageBoxResult.Yes)
            {
                int iAppend;
                string pathNew;
                foreach (FileInfo feFileToRename in toRename.Keys)
                {
                    iAppend = 0;
                    while (System.IO.File.Exists(pathNew = (iAppend == 0) ? feFileToRename.DirectoryName + "\\" + toRename[feFileToRename] : feFileToRename.DirectoryName + "\\" + iAppend.ToString() + "_" + toRename[feFileToRename]))
                        iAppend++;
                    System.IO.File.Move(feFileToRename.FullName, pathNew);
                }
                //
                MessageBox.Show(this, string.Format(Properties.Resources.Message_Done, messageToDisplay), "", MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }

        private void buttonBrowse_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog d1 = new System.Windows.Forms.FolderBrowserDialog();
            d1.Description = Properties.Resources.OpenFolderDesc;
            if (d1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                folderToSearch.Text = d1.SelectedPath;
            }
        }
    }
}
